home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / bm_src.arc / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-07  |  18.0 KB  |  803 lines

  1. /*
  2.  *    Simple mail user interface for KA9Q IP/TCP package.
  3.  *    A.D. Barksdale Garbee II, aka Bdale, N3EUA
  4.  *    Copyright 1986 Bdale Garbee, All Rights Reserved.
  5.  *    Permission granted for non-commercial copying and use, provided
  6.  *    this notice is retained.
  7.  *    Copyright 1987 1988 Dave Trulli NN2Z, All Rights Reserved.
  8.  *    Permission granted for non-commercial copying and use, provided
  9.  *    this notice is retained.
  10.  *
  11.  * revision history:
  12.  *
  13.  *  v3.3 870467 D. Trulli nn2z
  14.  *  v3.2 870314 D. Trulli nn2z
  15.  *  v3.1 870117 D. Trulli nn2z
  16.  *    Add multiple arguments mail commands.
  17.  *    Send to multiple users.
  18.  *    Add status commands;
  19.  *  v3.0 871225 D. Trulli nn2z
  20.  *    Heavily restructured program to use a index array of message.
  21.  *    More compatible with UNIX type mail commands.
  22.  *  v2.7 871214 D. Trulli nn2z
  23.  *    Cleaned up header and message parsing to prevent lock up.
  24.  *    Revised command structure.
  25.  *  v2.6 870826 Bdale
  26.  *    integrate PA0GRI's interface/gateway to the WA7MBL PBBS
  27.  *  v2.5 870713 Bdale
  28.  *      integrate additional patches from PA0GRI, minor cleanup
  29.  *  v2.4 870614 - P. Karn
  30.  *      "smart gateway" function moved to smtp client code in net.exe.
  31.  *    User interface for sending mail reworked to resemble Berkeley Mail
  32.  *  v2.3 870524
  33.  *      Extensive addition/revision by Gerard PA0GRI.  Now supports a healthy
  34.  *      set of real commands.  
  35.  *  v2.1,2.2
  36.  *      exact change history lost.
  37.  *  v2.0 c.870115
  38.  *      First version with command parser, only send and quit work.
  39.  *  v1.0
  40.  *      First attempt.  Send messages only.
  41.  */
  42.  
  43. #include <stdio.h>
  44. #if defined(__TURBOC__)
  45. #include <time.h>
  46. #endif
  47. #include <ctype.h>
  48. #include <string.h>
  49. #include "bm.h"
  50.  
  51. extern char version[];
  52. static char copyright1[] = 
  53. "Copyright 1987 Bdale Garbee, permission granted for non-commercial use.";
  54. static char copyright2[] = 
  55. "Copyright 1988 Dave Trulli NN2Z, permission granted for non-commercial use.";
  56.  
  57. /* comands valid in bm.rc */
  58.  
  59. struct token rccmds[] = {
  60.     "smtp", SMTP,
  61.     "host", HOST,
  62.     "user", USER,
  63.     "edit", EDIT,
  64.     "fullname", NAME,
  65.     "reply", REPLY,
  66.     "maxlet", MAXLET,
  67.     "mbox", MBOX,
  68.     "record", RECORD,
  69.     "screen", SCREEN,
  70.     "folder", FOLDER,
  71.     "mqueue", MQUEUE,
  72.     NULLCHAR, 0
  73. };
  74.  
  75. FILE    *mfile = NULLFILE;
  76. char     *hostname = NULLCHAR;        /* name of this host from rc file */
  77. char    *username = NULLCHAR;        /* name of this user from rc file */
  78. char    *fullname = NULLCHAR;        /* fullname of this user from rc file */
  79. char    *replyto = NULLCHAR;        /* address for reply-to header */
  80. char    *maildir = NULLCHAR;        /* defined mail directory */
  81. char    *mqueue = NULLCHAR;        /* defined mqueue outbound directory */
  82. char    *savebox = NULLCHAR;        /* name of the mbox text file */
  83. char    *record = NULLCHAR;        /* record  outbound mail in this file */
  84. char    *folder = NULLCHAR;        /* directory for saveing read mail */
  85. char    *editor = NULLCHAR;        /* user's favorite text editor */
  86. char    notename[9];            /* name of current notesfile */
  87. char    notefile[SLINELEN];        /* full pathname of mail text file */
  88. char    *mfilename = notefile;    /* pointer to current mbox or mail file -f */
  89. int    current;            /* the current message number */
  90. int    nmsgs;            /* the number of messages in the notesfile */
  91. int    newmsgs;        /* Number of new unread message */
  92. int    change;            /* indicates that the mail file has been
  93.                  * changed in this session */
  94. int    fflag = 0;        /* true if current notesfile is not an mbox */
  95. int    qflag = 0;        /* true if bm is used just to queue files */
  96. unsigned maxlet = NLET+1;    /* max number of messages in mailbox */
  97. int    tty = 0;        /* tells if stdin is a tty */
  98. struct let *mbox;        /* pointer to the array of messages */
  99.  
  100.  
  101. char usage[] = "Usage: bm [-u user] [-f file] \n  or bm [-s subject] [-q] addr .. addr\n";
  102. char badmsg[] = "Invalid Message number %d\n";
  103. char nomail[] = "No messages\n";
  104. char noaccess[] = "Unable to access %s\n";
  105.  
  106. main(argc,argv)
  107. int argc;
  108. char *argv[];
  109. {
  110.     extern int optind;
  111.     extern char *optarg;
  112.     char *subjectline = NULLCHAR;
  113.     long    tmp;
  114.     int    c;
  115.     int    ret;
  116. #if    defined(PLUS)
  117.     extern int directvideo;
  118.     directvideo=0;
  119. #endif
  120.  
  121. #if    defined(__TURBOC__) || defined(MICROSOFT)
  122.     (void) fclose(stdaux);
  123.     (void) fclose(stdprn);
  124. #endif
  125.  
  126. #if defined(__TURBOC__)
  127.     tzset();
  128. #endif
  129.  
  130.     loadconfig();
  131.  
  132.     if (qflag == 0 && isatty(fileno(stdin))) {
  133.         /* announce ourselves */
  134.         screen_clear();
  135.         printf(" %s\n%s\n%s\n\n",version,copyright1,copyright2);
  136.         tty = 1;
  137.     } 
  138.  
  139.     current = 1;
  140.     nmsgs = 0;
  141.  
  142.     /* check for important directories */
  143.     if(access(maildir,0)){
  144.         printf(noaccess,maildir);
  145.         exit(1);
  146.     }
  147.     if(access(mqueue,0)){
  148.         printf(noaccess,mqueue);
  149.         exit(1);
  150.     }
  151.     strncpy(notename,username,8);
  152.     notename[8] = '\0';
  153.  
  154.     while ((c = getopt(argc,argv,"u:f:s:q")) != -1) {
  155.         switch(c) {
  156.         case 'f':
  157.             fflag++;
  158.             mfilename = optarg;
  159.             break;
  160.         case 'q':
  161.             qflag++;
  162.             break;
  163.         case 's':
  164.             subjectline = optarg;
  165.             break;
  166.         case 'u':
  167.             strncpy(notename,optarg,8);
  168.             notename[8] = '\0';
  169.             break;
  170.         case '?':
  171.             printf(usage);
  172.             exit(1);
  173.         }
  174.     }
  175.  
  176.     /* set any signal handlers to catch break */
  177.     setsignals();
  178.  
  179.     if(optind < argc){
  180.         dosmtpsend(NULLFILE,&argv[optind],argc-optind,subjectline);
  181.         (void) exit(0);
  182.     }
  183.  
  184.     tmp = (long)maxlet * (long)sizeof(struct let);
  185. #ifdef    MSDOS
  186.     /*
  187.     * Since we are in the dos small model make sure that we
  188.     * don't overflow a unsigned short on the number bytes
  189.     * need for mallloc. If not checked malloc will
  190.     * succeed and we will be trashing ourself in no time.
  191.     */
  192.     if ((tmp & 0xffff0000) ||
  193.         (mbox=(struct let *)malloc((unsigned short)tmp)) == (struct let *)NULL){
  194. #else
  195.     if ((mbox=(struct let *)malloc((unsigned)tmp)) == (struct let *)NULL){
  196. #endif
  197.         fprintf(stderr,
  198.         "Can't allocate memory table for %d messages\n",
  199.             maxlet);
  200.         (void) exit(1);
  201.     }
  202.  
  203.     sprintf(notefile,"%s/%s.txt",maildir,notename);
  204.     if (!fflag && lockit())
  205.         exit(1);
  206.     ret = initnotes();
  207.     if (!fflag)
  208.         rmlock(maildir,notename);
  209.     if (ret != 0)
  210.         exit(1);
  211.     listnotes();
  212.     
  213.     getcommand();
  214.     return 0;
  215. }
  216.  
  217. loadconfig()
  218. {
  219.     FILE    *rcfp;    /* handle for the configuration file */
  220.     char    rcline[LINELEN]; /* buffer for config file reading */
  221.     register char *s,*p;
  222.     int line = 0;
  223.     char runcom[LINELEN];
  224.     char *getenv();
  225.  
  226. #ifdef UNIX
  227.     /* Try $HOME/RUNCOM */
  228.     if ((p = getenv("HOME")) != NULLCHAR)
  229.         sprintf(runcom, "%s/%s", p, RUNCOM);
  230. #else
  231.     /* check for BMRC in the ENV */
  232.     if ((p = getenv("BMRC")) != NULLCHAR)
  233.         strcpy(runcom,p);
  234. #endif
  235.     else
  236.         strcpy(runcom,RUNCOM);
  237.  
  238.     if ((rcfp = fopen(runcom,"r")) == NULLFILE) {    /* open config file */
  239.         printf("Cannot open '%s', check your installation\n",runcom);
  240.         (void) exit(1);
  241.     }
  242.     while (!feof(rcfp)) {
  243.         if (fgets(rcline,LINELEN,rcfp) == NULLCHAR)
  244.             break;
  245.         line++;
  246.         rip(rcline);
  247.         if (*rcline == '\0' || *rcline == ';'|| *rcline == '#')
  248.             continue;
  249.         /* find the argument to the command */
  250.  
  251.         s = rcline;
  252.         /* skip the white space */
  253.         while(*s == ' ' || *s == '\t')
  254.                 s++;
  255.         p = s;
  256.         /* skip the command */
  257.         while(*p && *p != ' ' && *p != '\t')
  258.                 p++;
  259.         /* skip the white space */
  260.         while(*p == ' ' || *p == '\t')
  261.                 p++;
  262.         if (*s == '\0')
  263.             continue;
  264.  
  265.         switch (rc_line_type(s)) {
  266.         case HOST:
  267.             hostname = savestr(p);
  268.             break;
  269.         case USER:
  270.             username = savestr(p);
  271.             break;
  272.         case REPLY:
  273.             replyto = savestr(p);
  274.             break;
  275.         case EDIT:
  276.             editor = savestr(p);
  277.             break;
  278.         case SMTP:
  279.             maildir = savestr(p);
  280.             break;
  281.         case NAME:
  282.             fullname = savestr(p);
  283.             break;
  284.         case MAXLET:
  285.             maxlet = atoi(p)+1;
  286.             break;
  287.         case MBOX:
  288.             savebox = savestr(p);
  289.             break;
  290.         case RECORD:
  291.             record = savestr(p);
  292.             break;
  293.         case SCREEN:
  294. #if    defined(__TURBOC__)
  295.             setvideo(p);
  296. #endif
  297.             break;
  298.         case FOLDER:
  299.             folder = savestr(p);
  300.             break;
  301.         case MQUEUE:
  302.             mqueue = savestr(p);
  303.             break;
  304.         default:
  305.             fprintf(stderr,
  306.             "%s: line %d Invalid command: '%s'\n",
  307.             runcom,line,rcline);
  308.             exit(1);
  309.         }
  310.     }
  311.     (void) fclose(rcfp);
  312.     if(maildir == NULLCHAR)
  313.         maildir = mailspool;
  314.     if(mqueue == NULLCHAR)
  315.         mqueue = mailqdir;
  316.     if(savebox == NULLCHAR)
  317.         savebox = "mbox";
  318.     if(hostname == NULLCHAR) {
  319.         fprintf(stderr,"%s: hostname not set\n",runcom);
  320.         exit(1);
  321.     }
  322.     if(username == NULLCHAR) {
  323.         fprintf(stderr,"%s: username not set\n",runcom);
  324.         exit(1);
  325.     }
  326. }
  327.  
  328. /* return the line_type from a line of the configuration file */
  329. rc_line_type(s)
  330. register char *s;
  331. {
  332.     register struct token *tp;
  333.     for (tp = rccmds; tp->str != NULLCHAR; tp++) {
  334.         if (strncmp(tp->str,s,strlen(tp->str)) == 0)
  335.             return tp->type;
  336.     }
  337.     return (NONE);
  338. }
  339.  
  340. /* replace terminating end of line marker(s) with null */
  341. rip(s)
  342. register char *s;
  343. {
  344.     for (; *s; s++)
  345.         if (*s == '\r' || *s == '\n') {
  346.             *s = '\0';
  347.             break;
  348.         }
  349. }
  350.  
  351. /* copy a string return a pointer to it */
  352. char *
  353. savestr(s)
  354. char *s;
  355. {
  356.     register  char *p;
  357.     p = malloc(strlen(s)+1);
  358.     if (p == NULLCHAR) 
  359.         printf("No more memory\n");
  360.     else
  361.         strcpy(p,s);
  362.     return p;
  363. }
  364.  
  365. dohelp()
  366. {
  367.     screen_clear();
  368.     printf("\n\n");
  369.     printf(" d [msglist]           delete a message\n");
  370.     printf(" m userlist            mail a message\n");
  371.     printf(" s [msglist] [file]    save message in file (default mbox)\n");
  372.     printf(" w [msglist] file      save message in file no header\n");
  373.     printf(" f [msg]               forward message\n");
  374.     printf(" b [msg]               bounce message (remail)\n");
  375.     printf(" r [msg]               reply to a message\n");
  376.     printf(" u [msglst]            undelete a message\n");
  377.     printf(" p [msglst]            print message on printer (DOS only)\n");
  378.     printf(" .                     display current message\n");
  379.     printf(" h                     display message headers in notefile\n");
  380.     printf(" l                     list unsent messages\n");
  381.     printf(" k                     kill unsent messages\n");
  382.     printf(" n [file]              display or change notesfile\n");
  383.     printf(" #                     where # is the number of message to read\n");
  384.     printf(" x                     quit without changing mail file\n");
  385.     printf(" q                     quit\n");
  386.     printf(" ! cmd                 run dos command\n");
  387.     printf(" $                     sync the notefile\n");
  388.     printf(" ?                     print this help screen\n");
  389. }
  390.  
  391.  
  392. /* save a message list in a file in mailbox format */
  393. savemsg(argc,argv)
  394. int argc;
  395. register char *argv[];
  396. {
  397.     register char *savefile;
  398.     int msgnum;
  399.     int    i;
  400.     FILE *tfile;
  401.     char buf[LINELEN];
  402.  
  403.     if (mfile == NULLFILE){
  404.         printf(nomail);
  405.         return;
  406.     }
  407.     if (argc == 0 || isdigit(*argv[argc - 1])) {
  408.         savefile = savebox;
  409.     } else {
  410.         savefile = argv[argc - 1];
  411.         --argc;
  412.         /* if it is just a file name and not a path name then check
  413.         ** for a folder path defined and use that path to
  414.         ** save the file.
  415.         */
  416.         if (strpbrk(savefile,"/\\") == NULLCHAR && folder != NULLCHAR) {
  417.             sprintf(buf,"%s/%s",folder,savefile);
  418.             savefile = buf;
  419.         }
  420.     }
  421.     if ((tfile = fopen(savefile,"a")) == NULLFILE) {
  422.         perror(savefile);
  423.         return;
  424.     }
  425.     if (argc == 0)
  426.         msgtofile(current, tfile, 0);
  427.     else {
  428.         for (i = 0; i < argc; i++) {
  429.             msgnum = atoi(argv[i]);
  430.             if (msgnum >= 1 && msgnum <= nmsgs)
  431.                 msgtofile(msgnum, tfile, 0);
  432.             else
  433.                 printf(badmsg,msgnum);
  434.         }
  435.     }
  436.         (void) fclose(tfile);
  437.         printf("%s appended\n",savefile);
  438. }
  439.  
  440. #ifdef MSDOS
  441. /* send messages to the print device */
  442. printmsg(argc,argv)
  443. int argc;
  444. char *argv[];
  445. {
  446.     FILE *prn;
  447.     int msgnum;
  448.     int    i;
  449.  
  450.     if (mfile == NULLFILE){
  451.         printf(nomail);
  452.         return;
  453.     }
  454.     if ((prn = fopen("PRN","a")) == NULL) {
  455.         perror("PRN");
  456.         return;
  457.     }
  458.     if (argc == 0)
  459.         msgtofile(current, prn, 0);
  460.     else {
  461.         for (i = 0; i < argc; i++) {
  462.             msgnum = atoi(argv[i]);
  463.             if (msgnum >= 1 && msgnum <= nmsgs)
  464.                 msgtofile(msgnum, prn, 0);
  465.             else
  466.                 printf(badmsg,msgnum);
  467.         }
  468.     }
  469.     fclose(prn);
  470. }
  471. #endif
  472.  
  473. writemsg(argc,argv)
  474. int argc;
  475. char *argv[];
  476. {
  477.     char *writefile;
  478.     int msgnum;
  479.     int    i;
  480.     FILE *tfile;
  481.  
  482.     if (mfile == NULLFILE){
  483.         printf(nomail);
  484.         return;
  485.     }
  486.     if (argc == 0 || isdigit(*argv[argc - 1])) {
  487.         printf("no file specified\n");
  488.         return;
  489.     } else {
  490.         writefile = argv[argc - 1];
  491.         --argc;
  492.     }
  493.     if ((tfile = fopen(writefile,"a")) == NULLFILE) {
  494.         perror(writefile);
  495.         return;
  496.     }
  497.     if (argc == 0)
  498.         msgtofile(current, tfile, 1);
  499.     else {
  500.         for (i = 0; i < argc; i++) {
  501.             msgnum = atoi(argv[i]);
  502.             if (msgnum >= 1 && msgnum <= nmsgs)
  503.                 msgtofile(msgnum, tfile, 1);
  504.             else
  505.                 printf(badmsg,msgnum);
  506.         }
  507.     }
  508.     (void) fclose(tfile);
  509.     printf("%s appended\n",writefile);
  510. }
  511.  
  512. bmexit(x)
  513. int x;
  514. {
  515.     if(!fflag && lockit())
  516.         exit(1);
  517.     (void) closenotes();
  518.     if (!fflag)
  519.         rmlock(maildir,notename);
  520.     exit(x);
  521. }
  522.  
  523. /* this is the main command processing loop */
  524. getcommand()
  525. {
  526.     FILE *tfile, *tmpfile();
  527.     char    command[LINELEN];    /* command line */
  528.     char    *args[MAXARGS];
  529.     int    nargs;
  530.     char    *cp;
  531.     register int    msgnum;
  532.     register int    i;
  533.     int ret;
  534.  
  535.     printf("\nType ? for help.\n");
  536.  
  537.     /* command parsing loop */
  538.     while(1) {
  539.         printf("\"%s\"> ",notename);
  540.         gets(command);
  541.  
  542.         if (feof(stdin))        /* someone hit ^Z! */
  543.             strcpy(command,"q");    /* treat it like 'q' */
  544.             
  545.         if(*command == '!') {
  546.             if (system(&command[1]))
  547.                 perror("system");
  548.             continue;
  549.         }
  550.         if (*command) {
  551.             cp = command;
  552.             while (*cp && *cp != ' ')
  553.                 cp++;
  554.             nargs = parse(cp,args,MAXARGS);
  555.         }
  556.  
  557.         switch (*command) {
  558.         case 'm':        /* send msg */
  559.             if (nargs == 0) {
  560.                 printf("To: ");
  561.                 gets(command);
  562.                 nargs = parse(command,args,MAXARGS);
  563.             }
  564.             dosmtpsend(NULLFILE,args,nargs,NULLCHAR);
  565.             break;
  566.  
  567.         case 's':        /* save current msg to file */
  568.             savemsg(nargs,args);
  569.             break;
  570.  
  571.         case 'w':        /* write current msg to file */
  572.             writemsg(nargs,args);
  573.             break;
  574.  
  575.         case 'x':        /* abort */
  576.             (void) fclose(mfile);
  577.             (void) exit(0);
  578.             /* NOTREACHED */
  579.             break;
  580.  
  581.         case 'p':        /* print message */
  582. #ifdef MSDOS
  583.             printmsg(nargs,args);
  584. #else
  585.             printf("Command not available in this version\n");
  586. #endif
  587.             break;
  588.  
  589.         case 'r':            /* reply */
  590.             if (nargs == 0)
  591.                 msgnum = current;
  592.             else
  593.                 msgnum = atoi(args[0]);
  594.             if (msgnum >= 1 && msgnum <= nmsgs)
  595.                 reply(msgnum);
  596.             else
  597.                 printf(badmsg,msgnum);
  598.             break;
  599.  
  600.         case 'f':
  601.             if(nargs == 0)
  602.                 msgnum = current;
  603.             else 
  604.                 msgnum = atoi(args[0]);
  605.             if (msgnum < 1 || msgnum > nmsgs) {
  606.                 printf(badmsg,msgnum);
  607.                 break;
  608.             }
  609.             if((tfile = tmpfile()) == NULLFILE)
  610.                 printf("\nCannot open temp file\n");
  611.             else {
  612.                 msgtofile(msgnum,tfile,0);
  613.                 fseek(tfile,0L,0);
  614.                 printf("To: ");
  615.                 gets(command);
  616.                 nargs = parse(command,args,MAXARGS);
  617.                 dosmtpsend(tfile,args,nargs,NULLCHAR);
  618.                 (void) fclose(tfile);
  619.             }
  620.             break;
  621.  
  622.         case 'b':        /* bounce a message */
  623.             if(nargs == 0)
  624.                 msgnum = current;
  625.             else 
  626.                 msgnum = atoi(args[0]);
  627.             if (msgnum < 1 || msgnum > nmsgs) {
  628.                 printf(badmsg,msgnum);
  629.                 break;
  630.             }
  631.             if((tfile = tmpfile()) == NULLFILE)
  632.                 printf("\nCannot open temp file\n");
  633.             else {
  634.                 msgtofile(msgnum,tfile,0);
  635.                 fseek(tfile,0L,0);
  636.                 printf("To: ");
  637.                 gets(command);
  638.                 nargs = parse(command,args,MAXARGS);
  639.                 bouncemsg(tfile,args,nargs);
  640.                 (void) fclose(tfile);
  641.             }
  642.             break;
  643.  
  644.         case 'u':
  645.             if (nargs == 0)
  646.                 mbox[current].status &= ~DELETE;
  647.             else
  648.                 for (i = 0; i < nargs; i++) {
  649.                     msgnum = atoi(args[i]);
  650.                     if( msgnum >= 1 && msgnum <= nmsgs)
  651.                         mbox[msgnum].status &= ~DELETE;
  652.                     else
  653.                         printf(badmsg,msgnum);
  654.                 }
  655.             break;
  656.  
  657.         case 'l':        /* display unsent messages */
  658.             listqueue();
  659.             break;
  660.         case 'k':
  661.             if (nargs == 0)
  662.                 printf("No job id specified\n");
  663.             else
  664.                 for (i = 0; i < nargs; i++) 
  665.                     killjob(args[i]);
  666.             break;
  667.  
  668.         case 'n':     /* display or change notefiles */
  669.             mboxnames(nargs,args);
  670.             break;
  671.         case 'q':        /* quit */
  672.             if (isnewmail()) {
  673.                 printf("New mail has arrived\n");
  674.                 reinit();
  675.             } else
  676.                 bmexit(0);
  677.             /* NOTREACHED */
  678.             break;
  679.         case '$':
  680.             reinit();
  681.             break;
  682.  
  683.         case 'd':        /* delete a message */
  684.             if (nargs == 0)
  685.                 delmsg(current);
  686.             else
  687.                 for ( i = 0; i < nargs; i++) {
  688.                     msgnum = atoi(args[i]);
  689.                     if( msgnum >= 1 && msgnum <= nmsgs)
  690.                         delmsg(msgnum);
  691.                     else
  692.                         printf(badmsg,msgnum);
  693.                 }
  694.             break;
  695.  
  696.         case 'h':        /* list message headers in notesfile */
  697.  
  698.             listnotes();
  699.             break;
  700.  
  701.         case '\0':    /* a blank line prints next message */
  702.             printnext();
  703.             break;
  704.  
  705.         case '?':        /* help */
  706.             dohelp();
  707.             break;
  708.  
  709.         case  '.':
  710.             displaymsg(current);
  711.             break;
  712.         default:
  713.             if (!isdigit(*command))
  714.                 printf("Invalid command - ? for help\n");
  715.             else {
  716.                 msgnum = atoi(command);
  717.                 if (msgnum < 0 || msgnum > nmsgs)
  718.                     printf(badmsg,msgnum);
  719.                 else {
  720.                     current = msgnum;
  721.                     displaymsg(current);
  722.                 }
  723.             }
  724.             break;
  725.         }
  726.     }
  727. }
  728.  
  729. /* list or change mbox */
  730. mboxnames(argc,argv)
  731. int argc;
  732. char *argv[];
  733. {
  734.     register char *cp;
  735.     int ret;
  736.     char    line[80];
  737.     char    buf[LINELEN];
  738.  
  739.     if(argc != 0) {
  740.         if(!fflag && lockit())
  741.             return;
  742.         ret = closenotes();
  743.         if (!fflag)
  744.             rmlock(maildir,notename);
  745.             if (ret != 0)
  746.                 exit(1);
  747.             if (strpbrk(argv[0],"/\\") != NULLCHAR) {
  748.                 fflag = 1;
  749.                 mfilename = argv[0];
  750.             } else {
  751.                 fflag = 0;
  752.                 mfilename = notefile;
  753.                 strncpy(notename,argv[0],8);
  754.                 notename[8] = '\0';
  755.                 sprintf(notefile,"%s/%s.txt",maildir,notename);
  756.             }
  757.             if (!fflag && lockit()) {
  758.                 mfile = NULLFILE;
  759.                 printf("Mail file is busy\n");
  760.                 return;
  761.             }
  762.             ret = initnotes();
  763.             if (!fflag)
  764.                 rmlock(maildir,notename);
  765.             if (ret != 0)
  766.                 exit(1);
  767.             listnotes();
  768.  
  769.         } else {  /* he wants to see what notefiles there are */
  770.             sprintf(buf,"%s/*.txt",maildir,notename);
  771.             filedir(buf,0,line);
  772.             while(line[0] != '\0') {
  773.                 cp = strchr(line,'.');
  774.                 *cp = '\0';
  775.                 printf("notesfile -> %s\n",line);
  776.                 filedir(buf,1,line);
  777.             }
  778.         }
  779. }
  780.  
  781. reinit()
  782. {
  783.     int ret;
  784.     if (!fflag && lockit())
  785.         return;
  786.     ret = closenotes();
  787.     if (!fflag)
  788.         rmlock(maildir,notename);
  789.     if (ret != 0)
  790.         exit(1);
  791.     if (!fflag && lockit()) {
  792.         mfile = NULLFILE;
  793.         printf("Mail file is busy\n");
  794.         return;
  795.     }
  796.     ret = initnotes();
  797.     if (!fflag)
  798.         rmlock(maildir,notename);
  799.     if (ret != 0)
  800.         exit(1);
  801.     listnotes();
  802. }
  803.